package com.blue.wechat.auth;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 微信签名认证工具类
 * 
 * @author zhengj
 * @since 1.0 2017年2月20日
 */
public class SignUtil
{
	private SignUtil()
	{
	}
	
	/**
	 * 微信消息签名
	 * 
	 * @param token 令牌
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @return 签名
	 */
	public static String wechatMessage(String token, String timestamp, String nonce)
	{
		SortedSet<String> set = new TreeSet<>();
		set.add(token);
		set.add(timestamp);
		set.add(nonce);
		StringBuilder sb = new StringBuilder();
		for (String s : set)
		{
			sb.append(s);
		}
		return DigestUtils.sha1Hex(sb.toString());
	}
	
	/**
	 * 微信消息签名
	 * 
	 * @param token 令牌
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @param encrypt 密文
	 * @return 签名
	 */
	public static String wechatMessage(String token, String timestamp, String nonce, String encrypt)
	{
		SortedSet<String> set = new TreeSet<>();
		set.add(token);
		set.add(timestamp);
		set.add(nonce);
		set.add(encrypt);
		StringBuilder sb = new StringBuilder();
		for (String s : set)
		{
			sb.append(s);
		}
		return DigestUtils.sha1Hex(sb.toString());
	}
	
	/**
	 * js-api-ticket 签名
	 * 
	 * @param noncestr 随机字符串
	 * @param ticket js-api-ticket
	 * @param timestamp 时间戳
	 * @param url 当前网页的URL，不包含#及其后面部分
	 * @return 签名
	 */
	public static String jsApiTicket(String noncestr, String ticket, String timestamp, String url)
	{
		Map<String, String> map = new HashMap<>();
		map.put("noncestr", noncestr);
		map.put("jsapi_ticket", ticket);
		map.put("timestamp", timestamp);
		map.put("url", url);
		return sign(map);
	}
	
	/**
	 * 签名
	 * 
	 * @param map key-value 签名
	 * @return 签名
	 */
	private static String sign(Map<String, String> map)
	{
		Set<String> set = new TreeSet<>();
		for (Map.Entry<String, String> entry : map.entrySet())
		{
			set.add(entry.getKey() + "=" + entry.getValue());
		}
		String text = StringUtils.join(set, '&');
		return DigestUtils.sha1Hex(text);
	}
	
}
